package com.uzhie.web.controller.websocket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.uzhie.web.bean.RequestBean;
import com.uzhie.web.bean.ResponseBean;
import com.uzhie.web.bean.ResponseBodyBean;
import org.apache.log4j.Logger;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.PongMessage;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.lang.reflect.InvocationTargetException;
import java.util.Map;

/**
 * Created by Coder on 2018/7/10.
 */
public class WebsocketHandler extends TextWebSocketHandler {

    private Logger logger = Logger.getLogger(this.getClass());

    private Map<String, WebsocketClassMethod> classMethodMap;

    //private LocalVariableTableParameterNameDiscoverer tableParameterNameDiscoverer;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        logger.info("enter method afterConnectionEstablished");
        super.afterConnectionEstablished(session);
    }

    @Override
    protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {
        super.handlePongMessage(session, message);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        logger.info("enter method handleTextMessage");
        ResponseBodyBean result = null;
        Integer responseCode = 200;
        String responseMsg = "请求成功";
        RequestBean<JSONObject> requestBean = parseRequest(message.getPayload());
        try {
            requestBean = parseRequest(message.getPayload());
            if (classMethodMap.containsKey(requestBean.getRequestMethod())) {
                WebsocketClassMethod requestMethod = classMethodMap.get(requestBean.getRequestMethod());
                result = (ResponseBodyBean) requestMethod.getMethod().invoke(requestMethod.getClazzIns(), requestBean.getRequestBody());
            } else {
                throw new IllegalAccessException("请求方法未找到");
            }
        } catch (RuntimeException | InvocationTargetException | IllegalAccessException e) {
            if (e instanceof IllegalAccessException) {
                responseCode = 404;
                responseMsg = e.getMessage();
            } else {
                responseCode = 500;
                responseMsg = e.getMessage();
            }
        } finally {
            ResponseBean responseBean = new ResponseBean();
            responseBean.setRequestId("");
            responseBean.setRequestMethod(requestBean.getRequestMethod());
            responseBean.setResponseCode(responseCode);
            responseBean.setResponseMsg(responseMsg);
            responseBean.setResponseBody(result);
            session.sendMessage(new TextMessage(JSON.toJSONString(responseBean, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullNumberAsZero)));
            logger.info("响应消息结束");
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        logger.info("enter method handleTransportError");
        super.handleTransportError(session, exception);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        logger.info("enter method afterConnectionClosed");
        super.afterConnectionClosed(session, status);
    }

    /**
     * 转换请求json 将请求json转换成RequestBean
     *
     * @param payload
     * @return
     * @throws RuntimeException
     */
    private RequestBean<JSONObject> parseRequest(String payload) throws RuntimeException {
        return JSON.parseObject(payload, RequestBean.class);
    }

}
